import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:marquee_switcher/src/marquee_widget.dart';

import 'my_slide_transition.dart';

typedef IndexGestureTapCallback = Function(int);

class MarqueeSwitcher extends StatefulWidget {
  final int length;
  final IndexedWidgetBuilder itemBuilder;
  final Duration? itemShowMinDuration;
  final Duration? switchDuration;
  final Duration? endWaitDuration;
  final bool itemAutoScroll;
  final Duration? itemEndDelay;
  final IndexGestureTapCallback? onItemTap;
  final Alignment alignment;
  final double offsetY;
  final ValueChanged<int>? next;

  const MarqueeSwitcher({
    Key? key,
    required this.length,
    required this.itemBuilder,
    this.alignment = Alignment.centerLeft,
    this.itemShowMinDuration,
    this.switchDuration,
    this.endWaitDuration,
    this.itemAutoScroll = true,
    this.itemEndDelay,
    this.onItemTap,
    this.offsetY = 1,
     this.next,
  }) : super(key: key);

  @override
  MarqueeSwitcherState createState() => MarqueeSwitcherState();
}

class MarqueeSwitcherState extends State<MarqueeSwitcher>
    with SingleTickerProviderStateMixin {
  int _index = 0;
  Timer? timer;

  @override
  void didUpdateWidget(covariant MarqueeSwitcher oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.length > widget.length) {
      setState(() {
        if (_index != 0) timer?.cancel();
        _index = 0;
      });
    }
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedSwitcher(
        layoutBuilder: (currentChild, previousChildren) => Stack(
              alignment: widget.alignment,
              children: <Widget>[
                ...previousChildren,
                if (currentChild != null) currentChild,
              ],
            ),
        transitionBuilder: (widget, a) => FadeTransition(
              opacity: Tween<double>(begin: 0, end: 1).animate(a),
              child: MySlideTransition(
                position: Tween<Offset>(
                  begin: Offset(0, this.widget.offsetY),
                  end: Offset.zero,
                ).animate(a),
                child: widget,
              ),
            ),
        duration: widget.switchDuration ?? const Duration(milliseconds: 500),
        child: MarqueeWidget(
          key: ValueKey(_index),
          child: widget.itemBuilder(context, _index),
          callback: callback,
          autoScroller: widget.itemAutoScroll,
          autoScrollDelay: widget.itemEndDelay,
          onTap: widget.onItemTap == null
              ? null
              : () {
                  widget.onItemTap?.call(_index);
                },
        ));
  }

  ///item的回调，会回调动画播放的时间
  void callback(Duration duration) {
    var minDuration = widget.itemShowMinDuration ?? const Duration(seconds: 3);
    int m = max(0, minDuration.inMilliseconds - duration.inMilliseconds);
    var endD = widget.endWaitDuration ?? const Duration(milliseconds: 500);
    Duration d = Duration(milliseconds: m + endD.inMilliseconds);
    timer?.cancel();
    timer = Timer(d, () {
      next();
    });
    // Future.delayed(d, next);
  }

  //切换到下一个widget
  void next() {
    if (mounted) {
      setState(() {
        if (_index == widget.length - 1) {
          _index = 0;
        } else {
          _index += 1;
        }
        widget.next?.call(_index);
      });
    }
  }

  ///重置游标位置
  void resetIndex() {
    setState(() {
      if (_index != 0) timer?.cancel();
      _index = 0;
    });
  }

  @override
  void dispose() {
    super.dispose();
    timer?.cancel();
  }
}
